package com.itfreer.data.general;

import com.itfreer.data.general.utils.ValueConvertUtils;
import com.itfreer.utils.DateUtils;
import com.itfreer.utils.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 定义基于Map对象的查询条件
 */
public class QueryMap implements IQueryMap {

	private boolean addCaption = false;
	private String selectFields;

	private HashMap<String, Object> whereMap = new HashMap<String, Object>();
	private HashMap<String, Object> orderMap = new HashMap<String, Object>();
	private List<String> groupMap = new ArrayList<String>();

	/**
	 * 获取或设置页面值大小
	 */
	private int pageSize = 25;
	/**
	 * 获取或设置当前页面索引
	 */
	private int pageIndex = 1;

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int value) {
		if (value <= 0)
			pageSize = 25;
		else
			pageSize = value;
	}

	public int getPageIndex() {
		return pageIndex;
	}

	/**
	 * 设置页面索引
	 * 
	 * @param value
	 */
	public void setPageIndex(int value) {
		pageIndex = value;
	}

	@Override
	public void setAddCaptionField(boolean value) {
		this.addCaption = value;
	}

	@Override
	public boolean getAddCaptionField() {
		return addCaption;
	}

	@Override
	public String getSelectFields() {
		return selectFields;
	}

	@Override
	public void setSelectFields(String selectFields) {
		this.selectFields = selectFields;
	}

	@Override
	public HashMap<String, Object> getWhereMap() {
		return whereMap;
	}

	@Override
	public void setWhereMap(HashMap<String, Object> whereMap) {
		this.whereMap = whereMap;
	}

	@Override
	public List<String> getGroupMap() {
		return groupMap;
	}

	@Override
	public void settGroupMap(List<String> groupMap) {
		this.groupMap = groupMap;
	}

	@Override
	public HashMap<String, Object> getOrderByMap() {
		return orderMap;
	}

	@Override
	public void setOrderByMap(HashMap<String, Object> orderMap) {
		this.orderMap = orderMap;
	}

	@Override
	public int getKey() {
		String hashCode = "";
		//	if (!StringUtils.IsNullOrEmpty(this.getSelectFields()))
		//		hashCode += this.getSelectFields();
		//	else
		//		hashCode += "*";
		if (whereMap == null) {
			hashCode += "_null";
		} else {
			hashCode = whereMap.toString();
		}

		if (groupMap == null) {
			hashCode += "_null";
		} else {
			hashCode = groupMap.toString();
		}

		if (orderMap == null) {
			hashCode += "_null";
		} else {
			hashCode = orderMap.toString();
		}

		hashCode += "_" + this.getAddCaptionField() + "_" + this.getPageIndex()
				+ "_" + this.getPageSize();
		return hashCode.hashCode();
	}

	/**
	 * 获取参数对象
	 */
	@Override
	public WherePara getSql(ITable owerTable, boolean isAllSelectFiled) {
		WherePara para = new WherePara();
		// 查看是否为Oracle
		boolean isOracleWorksapce = false;
		if (whereMap != null) {
			para.whereString = getWhere(owerTable, whereMap, para.whereParas,
					isOracleWorksapce, true);
		}

		String sql = "";
		if (StringUtils.IsNullOrSpace(getSelectFields())) {
			setSelectFields("*");
		}
		
		if(isAllSelectFiled){
			sql = "select " + owerTable.getSelectFields(false) + " from "
					+ owerTable.getTableName();
		} else {
			if (getSelectFields().trim().equals("*")) {
				sql = "select " + owerTable.getSelectFields(false) + " from "
						+ owerTable.getTableName();
			} else {
				sql = "select " + getSelectFields() + " from "
						+ owerTable.getTableName();
			}
		}

		if (!StringUtils.IsNullOrSpace(para.whereString)) {
			sql += " where " + para.whereString;
		}

		String groupString = "";
		if (groupMap != null) {
			for (String item : groupMap) {
				groupString += item + ",";
			}
		}
		if (groupString != "") {
			groupString = groupString.substring(0, groupString.length() - 1);
		}
		if (!StringUtils.IsNullOrSpace(groupString))
			sql += " group by " + groupString;

		String orderString = "";
		if (orderMap != null) {
			Set<String> keys = orderMap.keySet();
			for (String key : keys) {
				if (orderMap.get(key).toString().equals("1")) {
					orderString += key + " ASC ,";
				} else {
					orderString += key + " DESC ,";
				}
			}
		}
		if (orderString != "") {
			orderString = orderString.substring(0, orderString.length() - 1);
		}

		if (!StringUtils.IsNullOrSpace(orderString))
			sql += " order by " + orderString;
		para.sql = sql;
		return para;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static String getWhere(ITable owerTable,
			HashMap<String, Object> wheremap, List<GlobalParameter> glo,
			boolean isOracleWorksapce, boolean isAnd) {
		String whereString = "";
		Set<String> keys = wheremap.keySet();
		for (String key : keys) {
			String[] fields = key.split(":");
			String field = null;
			String option = null;
			if (fields.length == 2) {
				field = fields[0];
				option = fields[1];
			} else {
				field = key;
				option = "=";
			}

			// 如果是or操作符
			if (field.trim().toLowerCase().equals("or")) {
				Object value = wheremap.get(key);
				if (value instanceof Map) {
					HashMap<String, Object> orWhereMap = (HashMap<String, Object>) value;
					if (orWhereMap != null) {
						String orWhereString = getWhere(owerTable, orWhereMap,
								glo, isOracleWorksapce, false);
						if (!orWhereString.equals("")) {
							if (isAnd) {
								whereString += "(" + orWhereString + ") and ";
							} else {
								whereString += "(" + orWhereString + ") or ";
							}
						}
					}
				} else if (value instanceof List) {
					List list = (List) value;
					String listWhere = "";
					for (Object item : list) {
						HashMap<String, Object> orWhereMap = (HashMap<String, Object>) item;
						if (orWhereMap != null) {
							String orWhereString = getWhere(owerTable,
									orWhereMap, glo, isOracleWorksapce, false);
							if (!orWhereString.equals("")) {
								listWhere += "(" + orWhereString + ") or ";
							}
						}
					}
					if (!listWhere.equals("")) {
						if (isAnd) {
							whereString += "("
									+ listWhere.substring(0,
											listWhere.length() - 3) + ") and ";
						} else {
							whereString += "("
									+ listWhere.substring(0,
											listWhere.length() - 3) + ") or ";
						}
					}
				}
			} else if (field.trim().toLowerCase().equals("and")) {
				Object value = wheremap.get(key);
				if (value instanceof Map) {
					HashMap<String, Object> orWhereMap = (HashMap<String, Object>) value;
					if (orWhereMap != null) {
						String orWhereString = getWhere(owerTable, orWhereMap,
								glo, isOracleWorksapce, true);
						if (!orWhereString.equals("")) {
							if (isAnd) {
								whereString += "(" + orWhereString + ") and ";
							} else {
								whereString += "(" + orWhereString + ") or ";
							}
						}
					}
				} else if (value instanceof List) {
					List list = (List) value;
					String listWhere = "";
					for (Object item : list) {
						HashMap<String, Object> orWhereMap = (HashMap<String, Object>) item;
						if (orWhereMap != null) {
							String orWhereString = getWhere(owerTable,
									orWhereMap, glo, isOracleWorksapce, true);
							if (!orWhereString.equals("")) {
								listWhere += "(" + orWhereString + ") and ";
							}
						}
					}
					if (!listWhere.equals("")) {
						if (isAnd) {
							whereString += "("
									+ listWhere.substring(0,
											listWhere.length() - 3) + ") and ";
						} else {
							whereString += "("
									+ listWhere.substring(0,
											listWhere.length() - 3) + ") or ";
						}
					}
				}
			} else {
				String innerWhere = getInnerWhere(owerTable, glo,
						isOracleWorksapce, wheremap.get(key), field, option);
				if (!innerWhere.equals("")) {
					if (isAnd) {
						whereString += innerWhere + " and ";
					} else {
						whereString += innerWhere + " or ";
					}
				}
			}
		}

		if (whereString != "") {
			if (isAnd) {
				whereString = whereString
						.substring(0, whereString.length() - 4);
			} else {
				whereString = whereString
						.substring(0, whereString.length() - 3);
			}
		}
		return whereString;
	}

	/**
	 * 获取单个Map的对象
	 * 
	 * @param owerTable
	 *            所属表
	 * @param glo
	 *            条件对象集
	 * @param isOracleWorksapce
	 *            是否为oracel数据库
	 * @param value
	 *            当前值
	 * @param field
	 *            当前字段
	 * @param option
	 *            当前操作符
	 * @return
	 */
	private static String getInnerWhere(ITable owerTable,
			List<GlobalParameter> glo, boolean isOracleWorksapce, Object value,
			String field, String option) {

		String whereString = "";
		boolean isDateField = false;
		if (isOracleWorksapce) {
			// 处理数据类型，确保Oracle等数据库在日期等数据查询时不出错
			Field f = owerTable.getField(field);
			if (f != null
					&& (f.getDataType() == GlobalDataType.Date || f
							.getDataType() == GlobalDataType.DateTime)) {
				isDateField = true;
				value = ValueConvertUtils.ConvertValue(f.getDataType(), null,
						value);
			}
		}

		if (option.equals("=")) {
			if (value == null || value.equals("")) {
				return whereString;
			}
			if (value.equals("\"null\"")) {
				whereString = field + " is null";
			} else {
				if (isOracleWorksapce && isDateField) {
					String dataString = DateUtils
							.convertDateTimeToString((Date) value);
					whereString = field + " = to_date('" + dataString
							+ "','yyyy-mm-dd hh24:mi:ss')";
				} else {
					whereString = field + " = @" + field + "";
					glo.add(new GlobalParameter("@" + field, value));
				}
			}
		} else if (option.equals(">")) {
			if (value == null || value.equals("")) {
				return whereString;
			}
			if (isOracleWorksapce && isDateField) {
				String dataString = DateUtils
						.convertDateTimeToString((Date) value);
				whereString = field + " > to_date('" + dataString
						+ "','yyyy-mm-dd hh24:mi:ss')";
			} else {
				whereString = field + " > @" + field + "";
				glo.add(new GlobalParameter("@" + field, value));
			}
		} else if (option.equals("!=")) {
			if (value == null || value.equals("")) {
				return whereString;
			}
			if (isOracleWorksapce && isDateField) {
				String dataString = DateUtils
						.convertDateTimeToString((Date) value);
				whereString = field + " != to_date('" + dataString
						+ "','yyyy-mm-dd hh24:mi:ss')";
			} else {
				whereString = field + " != @" + field + "";
				glo.add(new GlobalParameter("@" + field, value));
			}
		} else if (option.equals(">=")) {
			if (value == null || value.equals("")) {
				return whereString;
			}
			if (isOracleWorksapce && isDateField) {
				String dataString = DateUtils
						.convertDateTimeToString((Date) value);
				whereString = field + " >= to_date('" + dataString
						+ "','yyyy-mm-dd hh24:mi:ss')";
			} else {
				whereString = field + " >= @" + field + "";
				glo.add(new GlobalParameter("@" + field, value));
			}
		} else if (option.equals("<")) {
			if (value == null || value.equals("")) {
				return whereString;
			}
			if (isOracleWorksapce && isDateField) {
				String dataString = DateUtils
						.convertDateTimeToString((Date) value);
				whereString = field + " < to_date('" + dataString
						+ "','yyyy-mm-dd hh24:mi:ss')";
			} else {
				whereString = field + " < @" + field + "";
				glo.add(new GlobalParameter("@" + field, value));
			}
		} else if (option.equals("<=")) {
			if (value == null || value.equals("")) {
				return whereString;
			}
			if (isOracleWorksapce && isDateField) {
				String dataString = DateUtils
						.convertDateTimeToString((Date) value);
				whereString = field + " <= to_date('" + dataString
						+ "','yyyy-mm-dd hh24:mi:ss')";
			} else {
				whereString = field + " <= @" + field + "";
				glo.add(new GlobalParameter("@" + field, value));
			}
		} else if (option.equals("in")) {
			if (value == null || value.equals("")) {
				return whereString;
			}
			whereString = field + " in (" + value.toString() + ")";
		} else if (option.equals("nin")) {
			if (value == null || value.equals("")) {
				return whereString;
			}
			whereString = field + " not in (" + value.toString() + ")";
		} else if (option.equals("isnull")) {
			whereString = field + " is null";
		} else if (option.equals("isnnull")) {
			whereString = field + " is not null";
		} else if (option.equals("like")) {
			if (value == null || value.equals("")) {
				return whereString;
			}
			whereString = field + " like '%" + value.toString() + "%'";

		} else if (option.equals("%like")) {
			whereString = field + " like '%" + value.toString() + "'";
		} else if (option.equals("like%")) {
			whereString = field + " like '" + value.toString() + "%'";
		} else {
			throw new RuntimeException("不支持的操作符【" + option + "】！");
		}
		return whereString;
	}
}